<!--
 * @Author: your name
 * @Date: 2020-08-25 21:56:30
 * @LastEditTime: 2021-04-26 22:12:01
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \adminPC\src\components\JTable\index.vue
-->
<template>
  <div class="wrapper">
    <el-row v-if="searchList.length" class="searchBox" :gutter="20">
      <el-form ref="listQuery" :model="listQuery" :label-width="searchTipWidth">
        <el-col v-for="(item,k) in searchList" :key="k" :span="6">
          <el-form-item class="sraechItem" :label="`${item.label}:`">
            <el-input v-model.trim="listQuery[item.prop]" :placeholder="item.label" clearable />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-button type="primary" icon="el-icon-search" @click="handlerPagination('searchBtn')">搜索</el-button>
          <el-button icon="el-icon-refresh-left" @click="handlerPagination('refresh')">重置</el-button>
        </el-col>
      </el-form>
    </el-row>
    <el-row class="activeBox" :gutter="20">
      <el-col :span="12">
        <el-button v-if="defaultBtnShow('created')" type="primary" icon="el-icon-edit" @click="bindActive('created')">新增</el-button>
        <slot name="activeBoxR" />
      </el-col>
      <el-col :span="12">
        <slot name="activeBoxL" />
      </el-col>
    </el-row>
    <el-table
      ref="multipleTable"
      v-loading="config.listLoading"
      v-bind="modelAttribute"
      v-on="modelEvent"
    >
      <template v-for="(item,key) in config.thead">
        <el-table-column
          v-if="item.type&&['SELECTION'].includes(stringUpperCase(item.type))"
          :key="key"
          :width="item.width"
          :type="item.type"
          align="center"
        />
        <el-table-column
          v-else
          :key="key"
          :label="item.label"
          :type="item.type"
          :align="item.align"
          :width="item.width"
        >
          <template slot-scope="scope">
            <slot v-if="item.slot" :name="item.prop||item.label" v-bind="scope" />
            <template v-else>
              <span v-if="item.type&&['INDEX'].includes(stringUpperCase(item.type))">
                {{ scope.$index + item.start }}
              </span>
              <span v-else>
                {{ scope.row[item.prop] }}
              </span>
            </template>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页器 -->
    <Pagination
      v-show="listQuery.total&&listQuery.total>0"
      :total="listQuery.total||0"
      :page.sync="listQuery.page"
      :limit.sync="listQuery.size"
      @pagination="handlerPagination"
    />
  </div>
</template>

<script>
import Pagination from '@/components/Pagination'

export default {
  name: 'JTable',
  components: {
    Pagination
  },
  props: {
    tableList: {
      type: Array,
      default: () => ([])
    },
    config: {
      type: Object,
      default: () => ({
        listLoading: false,
        loadingText: '加载中',
        thead: []
      })
    }
  },
  data() {
    return { }
  },
  computed: {
    listQuery() {
      const originConfig = this.config && this.config.pagination || {
        total: 0,
        page: 1,
        size: 10
      }
      const listQuery = originConfig
      return listQuery
    },
    showList() {
      const result = this.tableList || []
      return result
    },
    searchTipWidth() {
      let width = 'auto'
      const { search: { labelWidth = '' } = {}} = this.config
      if (labelWidth) {
        width = labelWidth
      }
      return width
    },
    searchList() {
      const { search = [], thead } = this.config
      let searchArr = search
      if (!Array.isArray(searchArr)) {
        const { searchList = [] } = search
        searchArr = searchList
      }
      const result = searchArr.reduce((acc, cur, index, array) => {
        const item = thead.find(i => i.prop === cur)
        if (item) {
          acc.push(item)
        }
        return acc
      }, [])
      return result
    },
    modelAttribute() {
      let result = {}
      const data = this.showList
      const elementLoadingText = this.config.loadingText
      const tableAttribute = this.config.tableAttribute
      result = {
        data,
        'element-loading-text': elementLoadingText,
        border: true,
        'highlight-current-row': true,
        ...tableAttribute
      }
      return result
    },
    modelEvent() {
      const tableEvent = this.config.tableEvent || {}
      return {
        select: this.handleSelectionChange,
        'select-all': this.handleSelectAll,
        ...tableEvent
      }
    },
    selection() {
      return this.$refs.multipleTable.selection
    }
  },
  watch: {
    showList() {
      this.$nextTick(() => {
        this.toggleSelection()
      })
    }
  },
  created() {},
  updated() {},
  mounted() {
    this.toggleSelection()
  },
  methods: {
    bindActive(target) {
      const { activeBox = {}} = this.config
      activeBox.bindDefaultEvent && activeBox.bindDefaultEvent(target)
    },
    defaultBtnShow(target) {
      const { activeBox: { defaultBtn = true, btnRules = {}} = {}} = this.config
      let result = false
      if (defaultBtn === false) return result
      if (defaultBtn === true) result = defaultBtn
      if (Array.isArray(defaultBtn)) {
        result = defaultBtn.includes(target)
      }
      // 如果是 false 直接 return
      if (!result) return result
      // 匹配规则
      if (btnRules.rulesFuntion) {
        return btnRules.rulesFuntion(btnRules[target])
      }
      return result
    },
    stringUpperCase(string) {
      return string.toUpperCase()
    },
    handlerPagination(target) {
      const { listQuery, searchList = [] } = this
      const { handleFilter, size, page, total } = listQuery
      if (target === 'searchBtn') {
        this.config.pagination = { ...listQuery, page: 1 }
        this.$nextTick(() => {
          const searchs = searchList.reduce((acc, cur, index, array) => {
            const { prop } = cur
            const searchitem = listQuery[prop]
            if (searchitem) {
              acc[prop] = searchitem
            }
            return acc
          }, { page: 1, size })
          handleFilter && handleFilter(searchs)
        })
      }
      if (target === 'refresh') {
        this.config.pagination = { size, page, total }
        handleFilter && handleFilter({ size, page })
      }
    },
    toggleSelection() {
      const rows = this.showList
      const { selected = [] } = this.config
      rows.forEach(row => {
        if (selected.includes(row.id)) {
          // toggleRowSelection  这个方法是用来选中某一行（打勾）
          // row 是要选中的那一行
          // true 是为选中
          this.$refs.multipleTable.toggleRowSelection(row, true)
        }
      })
    },
    handleSelectionChange(selection, row) {
      // 默认选中 -由外部传入

      const { selected = [] } = this.config
      const { id } = row

      const select = selection.find(i => i.id === id)
      const index = selected.indexOf(id)
      if (select === undefined) {
        index > -1 && selected.splice(index, 1)
      } else {
        index === -1 && selected.push(id)
      }
      this.$emit('selectArr', selected)
    },
    handleSelectAll(selection) {
      const dataIds = this.showList.map(i => i.id)
      const { selected = [] } = this.config

      if (selection.length > 0) {
        dataIds.forEach(i => {
          if (!selected.includes(i)) {
            selected.push(i)
          }
        })
      } else {
        dataIds.forEach(i => {
          const index = selected.indexOf(i)
          index > -1 && selected.splice(index, 1)
        })
      }
      this.$emit('selectArr', selected)
    }
  }
}
</script>
<style lang="scss" scoped>
.wrapper{
  padding: 12px 6px;
  background: #ffffff;
  margin: 0px;
  /*  ::v-deep  label{
    // width:100% !important;
    text-align: justify;
    &:after {
      content: " ";
      display: inline-block;
      width: 100%;
    }
  } */
  .activeBox{
  margin-bottom: 18px;
  }
}
</style>
